// hooks/useRequest/queue.ts

// 请求队列项接口
interface QueueItem<T = any> {
    id: string;
    priority: number;
    execute: () => Promise<T>;
    resolve: (value: T | PromiseLike<T>) => void;
    reject: (reason?: any) => void;
}

/**
 * 请求队列类
 * 用于管理请求队列和并发控制
 */
class RequestQueue {
    private queue: QueueItem[] = [];
    private running: Set<string> = new Set();
    private maxConcurrent: number = 6; // 默认最大并发数
    private isProcessingScheduled = false; // 标志是否已安排处理

    /**
     * 设置最大并发数
     * @param max 最大并发数
     */
    setMaxConcurrent(max: number): void {
        this.maxConcurrent = max > 0 ? max : 1;
        this.processQueue();
    }

    /**
     * 添加请求到队列
     * @param item 队列项
     * @returns Promise
     */
    enqueue<T>(item: Omit<QueueItem<T>, 'resolve' | 'reject'>): Promise<T> {
        return new Promise<T>((resolve, reject) => {
            const queueItem: QueueItem<T> = {
                ...item,
                resolve,
                reject
            };

            // 添加到队列
            this.queue.push(queueItem);

            // 按优先级排序，高优先级在前
            this.queue.sort((a, b) => b.priority - a.priority);

            // 延迟处理队列，以收集同一事件循环中的所有请求
            if (!this.isProcessingScheduled) {
                this.isProcessingScheduled = true;
                Promise.resolve().then(() => {
                    this.processQueue();
                    this.isProcessingScheduled = false;
                });
            }
        });
    }

    /**
     * 取消队列中的请求
     * @param id 请求ID
     */
    cancel(id: string): void {
        // 从队列中移除
        const index = this.queue.findIndex(item => item.id === id);
        if (index !== -1) {
            const item = this.queue[index];
            this.queue.splice(index, 1);
            item.reject(new Error('Request cancelled'));
        }

        // 如果正在执行，标记为已取消（实际取消由调用方处理）
        if (this.running.has(id)) {
            this.running.delete(id);
        }
    }

    /**
     * 处理队列
     */
    private processQueue(): void {
        // 如果当前运行的请求数小于最大并发数，且队列中有等待的请求
        while (this.running.size < this.maxConcurrent && this.queue.length > 0) {
            const item = this.queue.shift()!;
            this.running.add(item.id);

            // 执行请求
            item.execute()
                .then(result => {
                    item.resolve(result);
                })
                .catch(error => {
                    item.reject(error);
                })
                .finally(() => {
                    this.running.delete(item.id);
                    this.processQueue(); // 处理下一个请求
                });
        }
    }

    /**
     * 获取队列长度
     */
    get length(): number {
        return this.queue.length;
    }

    /**
     * 获取当前运行的请求数
     */
    get runningCount(): number {
        return this.running.size;
    }

    /**
     * 清空队列
     */
    clear(): void {
        // 拒绝所有等待中的请求
        this.queue.forEach(item => {
            item.reject(new Error('Queue cleared'));
        });

        this.queue = [];
    }
}

// 导出请求队列单例
export const requestQueue = new RequestQueue();

/**
 * 添加请求到队列
 * @param id 请求ID
 * @param priority 优先级
 * @param execute 执行函数
 * @returns Promise
 */
export const enqueueRequest = <T>(
    id: string,
    priority: number,
    execute: () => Promise<T>
): Promise<T> => {
    return requestQueue.enqueue({
        id,
        priority,
        execute
    });
};

/**
 * 取消队列中的请求
 * @param id 请求ID
 */
export const cancelQueuedRequest = (id: string): void => {
    requestQueue.cancel(id);
};

/**
 * 设置最大并发数
 * @param max 最大并发数
 */
export const setMaxConcurrent = (max: number): void => {
    requestQueue.setMaxConcurrent(max);
};

/**
 * 清空请求队列
 */
export const clearRequestQueue = (): void => {
    requestQueue.clear();
}; 